#ifndef DATACENTER_H
#define DATACENTER_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QWebSocket>
#include <QStandardPaths>
#include <QDir>
#include "../debug.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QFile>
#include "../model/data.h"
#include "../network/netclient.h"

namespace model
{
class DataCenter : public QObject{
    Q_OBJECT
public:
    ~DataCenter();

    /// 单例模式实现
    static DataCenter* getInstance();

    /////////////////////////////////////////////
    ///辅助函数
    /////////////////////////////////////////////
    /// 获取登录会话id
    QString getLoginSessionId();
    /// 通过消息会话id,获取对应消息会话, 该函数实现主要是为了帮助上层修改右侧会话标题等信息
    ChatSessionInfo* findChatSessionById(const QString &chatSessionId);
    /// 通过好友id,获取对应消息会话
    ChatSessionInfo * findChatSessionByUserId(const QString &userId);
    /// 置顶特定会话
    void topChatSessionInfo(const ChatSessionInfo &chatSessionInfo);
    /// 设置/获取当前会话id
    void setCurrentChatSessionId(const QString &chatSessionId);
    QString getCurrentChatSessionId();
    /// 通过userId, 查看用户是否为好友
    UserInfo* findFriendById(const QString& userId);

    /////////////////////////////////////////////
    ///网络读写相关方法
    /////////////////////////////////////////////
    /// 读写个人信息
    void getMyselfAsync();
    UserInfo* getMyself();
    void resetMyself(std::shared_ptr<bite_im::GetUserInfoRsp> resp);

    /// 读写好友列表
    void getFriendListAsync();
    QList<UserInfo>* getFriendList();
    void resetFriendList(std::shared_ptr<bite_im::GetFriendListRsp> resp);

    /// 读写会话列表
    void getChatSessionListAsync();
    QList<ChatSessionInfo>* getChatSessionList();
    void resetChatSessionList(std::shared_ptr<bite_im::GetChatSessionListRsp> resp);

    /// 读写申请好友列表
    void getApplyListAsync();
    QList<UserInfo>* getApplyList();
    void resetApplyList(std::shared_ptr<bite_im::GetPendingFriendEventListRsp> resp);

    /// 读写最近消息列表
    void getRecentMessagesAsync(const QString& chatSessionId,bool updateUI);
    QList<Message>* getRecentMessages(const QString& chatSessionId);
    void resetRecentMessages(const QString &chatSessionId, std::shared_ptr<bite_im::GetRecentMsgRsp> resp);

    /// 聊天页面:发送消息/接收消息
    //发送文本消息
    void sendTextMessageAsync(const QString& chatSessionId, const QByteArray& content);
    //添加消息到消息列表中
    void addMessage(const Message& message);
    //增加未读消息数量
    void addUnread(const QString& chatSessionId);
    //获取未读消息数量
    int getUnread(const QString& chatSessionId);
    //清除未读消息数量
    void clearUnread(const QString& chatSessionId);

    /// 个人信息页面功能
    //修改昵称
    void changeNicknameAsync(const QString& nickname);
    void resetNickname(const QString& nickname);
    //修改签名
    void changeDescriptionAsync(const QString& description);
    void resetDescription(const QString& description);
    //验证码逻辑
    void getVerifyCodeAsync(const QString& phone);
    QString getVerifyCodeId();
    void resetVerifyCodeId(std::shared_ptr<bite_im::PhoneVerifyCodeRsp> resp);

    //电话号码逻辑
    void changePhoneAsync(const QString& phone, const QString& verifyCodeId, const QString& verifyCode);
    void resetPhone(const QString& phone);

    //修改头像
    void changeAvatarAsync(const QByteArray& avatar);
    void resetAvatar(const QByteArray& avatar);
    /// 用户信息界面功能
    //删除好友
    void deleteFriendAsync(const QString& userId);
    void removeFriend(const QString& userId);
    //申请好友
    void addFriendApplyAsync(const QString& userId);
    //同意好友申请
    void acceptFriendApplyAsync(const QString& userId);
    UserInfo removeFromApplyList(const QString& userId);
    //拒绝好友申请
    void rejectFriendApplyAsync(const QString& userId);

    /// 群聊界面功能
    //创建群聊会话
    void createGroupChatSessionAsync(const QList<QString>& list);

    //获取群聊会话的成员列表
    void getMemberListAsync(const QString& chatSessionId);
    QList<UserInfo>* getMemberList(const QString& chatSessionId);
    void resetMemberList(const QString& chatSessionId,const QList<bite_im::UserInfo>& memberList);

    //搜索好友功能
    void searchUserAsync(const QString& searchKey);
    QList<UserInfo>* getSearchFriendList();
    void resetSearchUserResult(const QList<bite_im::UserInfo>& userInfoList);

    //搜索历史消息
    void searchMessageBySearchKeyAsync(const QString& searchKey);
    QList<Message>* getSearchMessageResult();
    void resetSearchMessageResult(const QList<bite_im::MessageInfo>& messageList);

    void searchMessageByTimeAsync(const QDateTime& time1, const QDateTime& time2);

    /// 用户账密登录
    void userLoginAsync(const QString& username,const QString& password);
    void resetLoginSessionId(const QString& loginSessionId);

    /// 用户账密注册
    void userRegisterAsync(const QString& username,const QString& password);

    /// websocket启动 (因为应当进入主窗口后再初始化)
    void initWebsocket();

    ///用户电话登录
    void phoneLoginAsync(const QString& phone,const QString& verifyCode);
    ///用户电话注册
    void phoneRegisterAsync(const QString& phone,const QString& verifyCode);

    /// 发送图片消息
    void sendImageMessageAsync(const QString& chatSessionId,const QByteArray& content);
    /// 发送文件消息
    void sendFileMessageAsync(const QString& chatSessionId,const QByteArray& content,const QString& fileName);
    /// 发送语音消息
    void sendSpeechMessageAsync(const QString& chatSessionId,const QByteArray& content);
    /// 语音转文字请求
    void speechConvertTextAsync(const QString& fileId, const QByteArray& content);


    ////////////////////////////////////////////////////////////////////
    /// 异步获取文件内容
    /// /////////////////////////////////////////////////////////////////
    void getSingleFileAsync(const QString& fileId);



private:
    //////////////////////////////////////////////
    /// 成员变量
    //////////////////////////////////////////////
    //单例模式实现
    static DataCenter* instance;
    DataCenter();

    //保存登录会话id
    QString loginSessionId = "";

    //保存登录会话的用户信息
    UserInfo* myself = nullptr;

    //短信验证码的验证id
    QString phoneVerifyCodeId = "";

    ////////////
    /// NetClinet实例, 用于进行通信
    ////////////
    netWork::NetClient netClient;
    ////////////
    /// 主窗口左侧相关
    /// ////////
    //会话列表
    QList<ChatSessionInfo>* chatSessionList = nullptr;
    //好友列表
    QList<UserInfo>* friendList = nullptr;
    //好友申请列表
    QList<UserInfo>* applyList = nullptr;

    ////////////
    /// 主窗口中间相关
    /// ////////
    //当前选中的会话id
    QString currentChatSessionId = "";
    //每个会话的最近消息列表
    QHash<QString,QList<Message>>* recentMessages = nullptr;
    //每个会话的成员
    QHash<QString, QList<UserInfo>>* memberList = nullptr;
    //每个会话的未读消息个数
    QHash<QString, int>* unReadMessagesCount = nullptr;
    //好友搜索结果
    QList<UserInfo>* searchUserResult = nullptr;

    ////////////
    /// 主窗口右侧相关
    /// ////////
    //保存历史消息结果
    QList<Message>* searchMessageResult = nullptr;

    //////////////////////////////////////////////
    /// 数据读写相关方法
    //////////////////////////////////////////////
    void initDataFile();
    void saveDataFile();
    void loadDataFile();

signals:
    ///////////////////////////////////////////////
    /// 网络读写相关信号
    //////////////////////////////////////////////
    /// 个人信息获取
    void getMyselfDone();

    /// 标签页对应信息获取
    void getFriendListDone();
    void getChatSessionListDone();
    void getApplyListDone();

    /// 发送/接收信息
    //发送获取最近消息完成信号, 同时请求更新界面
    void getRecentMessageListDone(const QString& chatSessionId);
    //发送获取最近消息完成信号, 无需更新界面
    void getRecentMessageListDoneNoUI(const QString& chatSessionId);
    //发送消息完毕信号
    void sendMessageDone(const QByteArray &content, model::MessageType type, const QString &extraInfo);
    //更新消息会话列表项最后一条消息信号
    void updateLastMessage(const QString& chatSessionId);
    //更新消息展示区信号(在消息为当前选中会话新消息情况下)
    void receiveMessageDone(const Message& message);

    /// 个人信息界面相关功能
    void changeNicknameDone();
    void changeDescriptionDone();
    // 获取验证码完成信号,该信号会在手机号登录中使用
    void getVerifyCodeDone();
    // 电话号改变完成信号
    void changePhoneDone();
    // 头像完成改变信号
    void changeAvatarDone();

    /// 用户信息界面功能
    // 删除好友
    void deleteFriendDone();
    void clearCurrentSession();
    // 申请好友
    void addFriendApplyDone();
    // 收到"好友申请"通知
    void receiveFriendApplyDone();
    //同意添加好友
    void acceptFriendApplyDone(const QString& userId);
    //拒绝添加好友
    void rejectFriendApplyDone(const QString& userId);
    //收到"添加好友"通知
    void receiveFriendProcessDone();
    //收到 "同意添加好友"通知
    void receiveFriendProcessAccept(const UserInfo& userInfo);
    //收到 "拒绝添加好友"通知
    void receiveFriendProcessReject(const UserInfo& userInfo);
    //群聊会话创建完毕
    void createGroupChatSessionDone();
    //收到创建群聊会话的通知
    void receiveSessionCreateDone();

    //获取群聊会话的成员列表
    void getMemberListDone(const QString &chatSessionId);

    //搜索好友的信号
    void searchUserDone();
    void searchMessageDone();

    // 用户名登录/注册完毕的信号
    void userLoginDone(bool ok, const QString& reason);
    void userRegisterDone(bool ok, const QString& reason);

    // 电话登录/注册完毕的信号
    void phoneLoginDone(bool ok, const QString& reason);
    void phoneRegisterDone(bool ok, const QString& reason);
    ////////////////////////////////////////////////////
    /// 异步获取文件内容
    /// /////////////////////////////////////////////////
    void getSingleFileDone(const QString& fileId, const QByteArray& content);

    void speechConvertTextDone(const QString& fileId,const QString& text);
};
} //end namespace


#endif // DATACENTER_H


